#include <stdbool.h>
#include "bsp.h"
#include "timer_config.h"
#include "stm32f4xx_hal.h"

/* 通用控制定时器时钟源TIMxCLK = HCLK/2=84MHz */
/* 设定定时器频率为=TIMxCLK/(PWM_PRESCALER_COUNT+1) */
#define PWM_PRESCALER_COUNT (7)

// 0.2ms定时器
// #define BASIC_TIM TIM4
#define BASIC_TIM_IRQ_PRIO 10
#define BASIC_TIM_IRQn TIM4_IRQn

// 10ms定时器
// #define PVT_TIM TIM6
#define PVT_TIM_IRQ_PRIO 6
#define PVT_TIM_IRQn TIM6_DAC_IRQn

// PWM输出定时器
#define PR_MOTOR_P_Pin          GPIO_PIN_6
#define PR_MOTOR_P_GPIO_Port    GPIOC
#define PR_MOTOR_N_Pin          GPIO_PIN_7
#define PR_MOTOR_N_GPIO_Port    GPIOC

TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim6;

// TODO: 暂时使用cubemx生成的驱动，未做通用性适配
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *timHandle);

/* TIM4 init function */
void MX_TIM4_Init(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    htim4.Instance = TIM4;
    htim4.Init.Prescaler = 83;
    htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim4.Init.Period = 199;
    htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
    {
        ERROR_HANDLER();
    }

    // 启动定时器
    HAL_TIM_Base_Start_IT(&htim4);
}

/* TIM6 init function */
void MX_TIM6_Init(void)
{
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    htim6.Instance = TIM6;
    htim6.Init.Prescaler = 83;
    htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim6.Init.Period = 9999;
    htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
    {
        ERROR_HANDLER();
    }

    // 启动定时器
    HAL_TIM_Base_Start_IT(&htim6);
}


/* TIM3 init function */
// PWM配置, 20kHz
/* TIM3 init function */
void MX_TIM3_Init(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};

    htim3.Instance = TIM3;
    htim3.Init.Prescaler = PWM_PRESCALER_COUNT;
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = PWM_PERIOD_COUNT;
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    {
        ERROR_HANDLER();
    }
    sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
    if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
    {
        ERROR_HANDLER();
    }

    HAL_TIM_MspPostInit(&htim3);

    // 启动PWM输出，初始占空比为0，电机驱动芯片处于休眠/滑行模式
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *tim_baseHandle)
{
    if (tim_baseHandle->Instance == TIM3)
    {
        /* TIM3 clock enable */
        __HAL_RCC_TIM3_CLK_ENABLE();
    }
    else if (tim_baseHandle->Instance == TIM4)
    {
        /* TIM4 clock enable */
        __HAL_RCC_TIM4_CLK_ENABLE();

        /* TIM4 interrupt Init */
        HAL_NVIC_SetPriority(BASIC_TIM_IRQn, BASIC_TIM_IRQ_PRIO, 0);
        HAL_NVIC_EnableIRQ(BASIC_TIM_IRQn);
    }
    else if (tim_baseHandle->Instance == TIM6)
    {
        /* TIM6 clock enable */
        __HAL_RCC_TIM6_CLK_ENABLE();

        /* TIM6 interrupt Init */
        HAL_NVIC_SetPriority(PVT_TIM_IRQn, PVT_TIM_IRQ_PRIO, 0);
        HAL_NVIC_EnableIRQ(PVT_TIM_IRQn);
    }
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *tim_baseHandle)
{
    if (tim_baseHandle->Instance == TIM3)
    {
        /* Peripheral clock disable */
        __HAL_RCC_TIM3_CLK_DISABLE();
    }
    else if (tim_baseHandle->Instance == TIM4)
    {
        /* Peripheral clock disable */
        __HAL_RCC_TIM4_CLK_DISABLE();

        /* TIM4 interrupt Deinit */
        HAL_NVIC_DisableIRQ(BASIC_TIM_IRQn);
    }
    else if (tim_baseHandle->Instance == TIM6)
    {
        /* Peripheral clock disable */
        __HAL_RCC_TIM6_CLK_DISABLE();

        /* TIM6 interrupt Deinit */
        HAL_NVIC_DisableIRQ(PVT_TIM_IRQn);
    }
}

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *timHandle)
{

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if (timHandle->Instance == TIM3)
    {
        __HAL_RCC_GPIOC_CLK_ENABLE();
        /**TIM3 GPIO Configuration
        PC6     ------> TIM3_CH1
        PC7     ------> TIM3_CH2
        */
        GPIO_InitStruct.Pin = PR_MOTOR_P_Pin | PR_MOTOR_N_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    }
}

/**
  * @brief  设置TIM通道的占空比
	* @param  channel		通道	（1,2,3,4）
	* @param  compare		占空比
	*	@note 	无
  * @retval 无
  */
void TIM3_SetPWM_pulse(uint32_t channel, int compare)
{
    switch (channel)
    {
    case TIM_CHANNEL_1:
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, compare);
        break;
    case TIM_CHANNEL_2:
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, compare);
        break;
    default:
        break;
    }
}


// void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *tim_pwmHandle)
// {

//     if (tim_pwmHandle->Instance == TIM3)
//     {
//         /* TIM3 clock enable */
//         __HAL_RCC_TIM3_CLK_ENABLE();
//     }
// }

// void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *tim_pwmHandle)
// {

//     if (tim_pwmHandle->Instance == TIM3)
//     {
//         /* Peripheral clock disable */
//         __HAL_RCC_TIM3_CLK_DISABLE();
//     }
// }
